/*
面向对象编程(OOP)的三个基本特征是：封装、继承、多态      

  封装：封装是对象和类概念的主要特性。封装，把客观事物封装成抽象的类，并且把自己的部分属性和方法提供给其他对象调用, 而一部分属性和方法则隐藏。

  继承：面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力：它可以使用现有类的功能，并在无需重新编写原来的类的情况下对这些功能进行扩展。

  多态：允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果 。


Dart所有的东西都是对象，所有的对象都继承自Object类。

Dart是一门使用类和单继承的面向对象语言，所有的对象都是类的实例，并且所有的类都是Object的子类

一个类通常由属性和方法组成。

*/

// 自定义类 必须定义在main入口函数外面
class Person {
  // 定义属性
  String name = "TheShy";
  int age = 23;
  // 定义方法
  void getInfo() {
    print("${this.name}----${this.age}");
  }

  void setInfo(int age) {
    this.age = age;
  }
}

// 自定义类 需要初始化不可为null的实例字段，如果不初始化的话需要在属性前面加上late
class Person2 {
  late String name;
  late int age;
  //默认构造函数
  Person2(String name, int age) {
    this.name = name;
    this.age = age;
  }
  void printInfo() {
    print("${this.name}----${this.age}");
  }
}

// 命名构造函数
class Person3 {
  late String name;
  late int age;
  // 触发默认构造函数
  Person3(this.name, this.age);
  //  命名构造函数
  Person3.setInfo(String name, int age) {
    this.name = name;
    this.age = age;
  }
  void printInfo() {
    print("${this.name}----${this.age}");
  }
}

main() {
  // 1. 内置的类

  // Map 就是内置的类
  Map m = new Map();
  m["username"] = "张三";
  m.addAll({"age": 20});
  m.isEmpty;
  // print(m.isEmpty);
  // print(m);

  // 2. 使用自定义类

  // 先实例化
  // var p = new Person(); // 不指定类型
  Person p = new Person(); // 指定类型是Person
  // 可以调用类的属性和方法
  print(p.name);
  p.setInfo(18);
  p.getInfo();

  // 3. 默认构造函数
  // 当实例化类的时候 自动触发的方法就是构造函数
  Person2 p1 = new Person2('theshy', 20);
  p1.printInfo();

  // 4. 命名构造函数
  Person3 p3 = new Person3.setInfo('ts', 19);
  p3.printInfo();
}
